﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;

namespace LogWatcher.Common
{
    public class FileWatcher : IDisposable
    {
        private String file;
        private bool stopThread = false;
        private long lastSize = 0;
        private Thread watcher;

        public bool IsStarted { get; private set; }

        public event Action<String> UpdateText;

        public FileWatcher(string file)
        {
            this.file = file;
            this.watcher = new Thread(DoWatching);
        }

        public void Start()
        {
            if (IsStarted)
                throw new InvalidOperationException("Cannot start watcher: already started!");

            this.watcher.Start();
            IsStarted = true;
        }

        public void Stop()
        {
            if (!IsStarted)
                throw new InvalidOperationException("Cannot stop watcher: already stopped!");

            stopThread = true;
        }

        private void DoWatching()
        {
            while (!stopThread)
            {
                if (!File.Exists(file))
                {
                    OnUpdateText("");
                    Thread.Sleep(100);
                    continue;
                }

                long currentSize = new FileInfo(file).Length;
                if (currentSize != lastSize)
                {
                    using (StreamReader reader = new StreamReader(
                        new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
                    {
                        OnUpdateText(reader.ReadToEnd());
                    }

                    lastSize = currentSize;
                }

                Thread.Sleep(100);
            }

            IsStarted = false;
        }

        private void OnUpdateText(String text)
        {
            if (UpdateText != null)
                UpdateText(text);
        }

        public void Dispose()
        {
            Stop();
        }
    }
}
